#include "user.h"
#include "thread_pool.h"
#include <stdio.h>
#include <string.h>
#include <shadow.h>
#include <mysql/mysql.h>

//用户注册函数
//服务器接收参数为数据库连接、用户名、密码
int registerUser(MYSQL *conn,const char *username,const char* password){
    //TODO:判断数据库中是否有重复的用户名
    //如果有则返回跳出结束
    //如果没有则继续执行插入命令，将用户信息插入到数据库表中
    //if()
    printf("execute registerUser()\n");
    printf("即将插入进数据库中的username是%s,passwd是%s\n",username,password);
    
    printf("重新连接数据库\n");
    MYSQL* reconn;
    reconn = mysql_init(NULL);
    if(reconn == NULL){
        fprintf(stderr,"mysql_init() failed\n");
        return 0;
    }
    if(mysql_real_connect(reconn,"192.168.13.128","root","1234","CloudiskServer",0,NULL,0)==NULL){
    fprintf(stderr,"mysql_real_connect() failed\n");
    mysql_close(conn);
    return EXIT_FAILURE;
    }

    char query[256]={0};//查询缓冲区
    snprintf(query,sizeof(query),"insert into user_info(username,cryptpasswd)values('%s','%s')",username,password);
    printf("query:%s\n",query);
    if(mysql_query(reconn,query)){
        fprintf(stderr,"insert error: %s\n",mysql_error(conn));
        return 0;//注册失败
    }
    return 1;//注册成功
}

//用户登录函数
int loginUser(MYSQL *conn,const char *username,const char *password){
    printf("execute loginUser()\n");
    char query[256];
    snprintf(query,sizeof(query),"select cryptpasswd from user_info where username= '%s'",username);

    if(mysql_query(conn,query)){
        fprintf(stderr,"select error: %s\n",mysql_error(conn));
        return 0;//查询失败
    }

    MYSQL_RES *res = mysql_store_result(conn);
    if(res == NULL){
        fprintf(stderr,"mysql_store_result() failed: %s\n",mysql_error(conn));
        return 0;//查询失败
    }
    int num_rows = mysql_num_rows(res);//返回查询行数
    if(num_rows == 0){
        mysql_free_result(res);
        return 0;//用户名不存在
    }

    MYSQL_ROW row = mysql_fetch_row(res);
    const char *stored_password = row[0];
    mysql_free_result(res);

    if(strcmp(stored_password,password)==0){
        return 1;//登录成功
    }else{
        return 0;//密码错误
    }
}

//注册任务处理函数
void registerTaskHandler(task_t *task,MYSQL *conn){
    printf("execute registerTaskHandler()\n");
    //提取用户名和密码
    char username[128],password[128];
    sscanf(task->data,"%s %s",username,password);
    printf("username: %s,password: %s\n",username,password);
    if(registerUser(conn,username,password)){
        //返回注册成功消息
        const char *success_msg = "Registration successful\n";
        write(task->peerfd,success_msg,strlen(success_msg));
    }else{
        //返回注册失败消息
        const char *fail_msg = "Registration failed\n";
        write(task->peerfd,fail_msg,strlen(fail_msg));
    }
}

//登录任务处理函数
void loginTaskHandler(task_t *task,MYSQL *conn){
    //提取用户名和密码
    char username[128],password[128];
    sscanf(task->data,"%s %s",username,password);
    
    if(loginUser(conn,username,password)){
        //返回登录成功消息
        const char *success_msg = "Login successful\n";
        write(task->peerfd, success_msg, strlen(success_msg));
    }else{
        //返回登录失败消息
         const char *fail_msg = "Login failed\n";
        write(task->peerfd, fail_msg, strlen(fail_msg));
    }
}

static void get_setting(char *setting,char *passwd)
{
    int i,j;
    //取出salt,i 记录密码字符下标，j记录$出现次数
    for(i = 0,j = 0; passwd[i] && j != 4; ++i) {
        if(passwd[i] == '$')
            ++j;
    }
    strncpy(setting, passwd, i);
}

void loginCheck1(user_info_t * user)
{
    printf("loginCheck1.\n");
    train_t t;
    int ret;
    memset(&t, 0, sizeof(t));
    struct spwd * sp = getspnam(user->name);
    if(sp == NULL) {// 用户不存在的情况下
        t.len = 0;   
        t.type = TASK_LOGIN_SECTION1_RESP_ERROR;
        ret = sendn(user->sockfd, &t, 8);
        printf("check1 send %d bytes.\n", ret);
        return;
    }
    //用户存在的情况下
    char setting[100] = {0};
    //保存加密密文
    strcpy(user->encrypted, sp->sp_pwdp);
    //提取setting
    get_setting(setting, sp->sp_pwdp);
    t.len = strlen(setting);
    t.type = TASK_LOGIN_SECTION1_RESP_OK;
    strncpy(t.buff, setting, t.len);
    //发送setting
    ret = sendn(user->sockfd, &t, 8 + t.len);
    printf("check1 send %d bytes.\n", ret);
}

void loginCheck2(user_info_t * user, const char * encrypted)
{
    /* printf("loginCheck2.\n"); */
    int ret;
    train_t t;
    memset(&t, 0, sizeof(t));
    if(strcmp(user->encrypted, encrypted) == 0) {
        //登录成功
        user->status = STATUS_LOGIN;//更新用户登录成功的状态
        t.type = TASK_LOGIN_SECTION2_RESP_OK;
        t.len = strlen("/server/$ ");// 暂定将 /server/ 作为pwd传递给client 
        strcpy(t.buff, "/server/$ ");
        ret = sendn(user->sockfd, &t, 8 + t.len);
        printf("Login success.\n");
    } else {
        //登录失败, 密码错误
        t.type = TASK_LOGIN_SECTION2_RESP_ERROR;
        printf("Login failed.\n");
        ret = sendn(user->sockfd, &t, 8);
    }
    printf("check2 send %d bytes.\n", ret);
    return;
}

